package principal;

import javax.swing.SwingUtilities;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Rectangle;
import java.io.IOException;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.Timer;
import javax.media.*;
import java.sql.Time;

public class Main extends JFrame {

	private final static int MAX_LENGTH_PBAR = 362;
	
	private JPanel jContentPane=null;
	private JMenuBar menuBar=null;
	private JMenu fileMenu=null;
	private JMenu controlMenu=null;
	private JMenuItem openMenuItem=null;
	private JMenuItem closeMenuItem=null;
	private JMenuItem playMenuItem=null;
	private JMenuItem pauseMenuItem=null;
	private JMenuItem stopMenuItem=null;
	private JButton playButton;
	private JButton pauseButton;
	private JButton stopButton;
	private JButton forwardButton;
	private JButton rewindButton;
	private componentProgressBar progressBar=null;
	private JTextArea timeCompleted;
	private JTextArea timeLeft;
	private String filePath; 
	private boolean openedFile=false;
	private Player player;
	private MediaLocator mlr;
	private float rate=1;
	private Timer tActual;
	private Timer tRewind;
	private boolean rewind=false;
	int secRewind=0;
	
	private class componentProgressBar extends JComponent {
		
		private int length=0;
		
		public void setLength(int l) {
			length=l;
		}
		
		public void paint(Graphics g) {
			Graphics2D g2d=(Graphics2D) g;
		    GradientPaint gradient = new GradientPaint(10,20,Color.GREEN,30,60,Color.CYAN,true);
		    g2d.setPaint(gradient);
		    g2d.draw(new Rectangle(20,20,MAX_LENGTH_PBAR,25));
		    g2d.fill(new Rectangle(20,20,length,25));
		}
	}
	
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				Main thisClass = new Main();
				thisClass.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				thisClass.setVisible(true);
			}
		});
	}

	public Main() {
		super();
		initializeInterface();
	}

	private void initializeInterface() {
		this.setSize(623, 300);
		this.setContentPane(getPrincipalPanel());
		this.setJMenuBar(getPrincipalMenu());
		this.setTitle("Reproductor Multimedia");
		this.setVisible(true);
	}

	private JPanel getPrincipalPanel() {
		if (jContentPane == null) {
			jContentPane = new JPanel();
			jContentPane.setLayout(new BorderLayout());
			jContentPane.setBackground(new java.awt.Color(0,0,0));
			JPanel controlPanel=getControlPanel();
			JPanel progressPanel=getProgressPanel();
			jContentPane.add(controlPanel, BorderLayout.SOUTH);
			jContentPane.add(progressPanel, BorderLayout.CENTER);
			jContentPane.setVisible(true);
		}
		return jContentPane;
	}
	
	private JPanel getControlPanel() {
		playButton=createButton("/images/play.png", "Play");
		playButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent e) {
				play();
			}
		});
		pauseButton=createButton("/images/pause.png", "Pausa");
		pauseButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent e) {
				pause();
			}
		});
		stopButton=createButton("/images/stop.png", "Stop");
		stopButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent e) {
				stop();
			}
		});
		rewindButton=createButton("/images/rewind.png", "Rebobina");
		rewindButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent e) {
				rewind();
			}
		});
		forwardButton=createButton("/images/forward.png", "Avanza");
		forwardButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent e) {
				forward();
			}
		});
		JPanel areaControles=new JPanel();
		areaControles.setLayout(new GridLayout(1,5));
		areaControles.setBackground(new java.awt.Color(0,0,0));
		areaControles.add(rewindButton);
		areaControles.add(pauseButton);
		areaControles.add(playButton);
		areaControles.add(stopButton);
		areaControles.add(forwardButton);
		areaControles.setVisible(true);
		return areaControles;
	}
	
	private JButton createButton(String icon, String toolTip) {
		ImageIcon buttonIcon=new ImageIcon(getClass().getResource(icon));
		JButton button=new JButton(buttonIcon);
		button.setToolTipText(toolTip);
		button.setContentAreaFilled(false);
		button.setBorderPainted(false);
		button.setOpaque(false);
		button.setEnabled(false);
		button.setFocusable(false);
		return button;
	}
	
	private JPanel getProgressPanel() {
		JPanel progressPanel=new JPanel();
		progressPanel.setLayout(new BorderLayout());
		progressPanel.setBackground(new java.awt.Color(0,0,0));
		timeCompleted=new JTextArea("00:00");
		timeCompleted.setBackground(new java.awt.Color(0,0,0));
		timeCompleted.setEditable(false);
		timeCompleted.setFont(new Font(null, Font.BOLD, 20));
		timeCompleted.setForeground(Color.CYAN);
		timeCompleted.setMargin(new Insets(22,25,25,25));
		timeCompleted.setOpaque(false);
		timeCompleted.setToolTipText("Tiempo transcurrido");
		timeLeft=new JTextArea("-00:00");
		timeLeft.setBackground(new java.awt.Color(0,0,0));
		timeLeft.setEditable(false);
		timeLeft.setFont(new Font(null, Font.BOLD, 20));
		timeLeft.setForeground(Color.CYAN);
		timeLeft.setMargin(new Insets(22,25,25,25));
		timeLeft.setOpaque(false);
		timeLeft.setToolTipText("Tiempo restante");
		progressBar=new componentProgressBar();
		progressBar.setVisible(false);
		progressPanel.add(progressBar, BorderLayout.CENTER);
		progressPanel.add(timeCompleted, BorderLayout.WEST);
		progressPanel.add(timeLeft, BorderLayout.EAST);
		progressPanel.setVisible(true);
		return progressPanel;
	}
	
	private JMenuBar getPrincipalMenu() {
		if (menuBar==null) {
			menuBar=new JMenuBar();
			menuBar.setBackground(Color.BLACK);
			menuBar.setForeground(Color.CYAN);
			menuBar.setBorderPainted(false);
			menuBar.add(getFileMenu());
			menuBar.add(getControlMenu());
		}
		return menuBar;
	}
	
	private JMenu getFileMenu() {
		if (fileMenu==null) {
			fileMenu=new JMenu();
			fileMenu.setBackground(Color.BLACK);
			fileMenu.setForeground(Color.CYAN);
			ImageIcon menuIcon=new ImageIcon(getClass().getResource("/images/filemenu.png"));
			fileMenu.setIcon(menuIcon);
			fileMenu.setToolTipText("Archivo");
			fileMenu.add(getOpenMenuItem());
			fileMenu.add(getCloseMenuItem());
		}
		return fileMenu;
	}
	
	private JMenu getControlMenu() {
		if (controlMenu==null) {
			controlMenu=new JMenu();
			controlMenu.setBackground(Color.BLACK);
			controlMenu.setForeground(Color.CYAN);
			ImageIcon menuIcon=new ImageIcon(getClass().getResource("/images/controlmenu.png"));
			controlMenu.setIcon(menuIcon);
			controlMenu.setToolTipText("Controles");
			controlMenu.add(getPlayMenuItem());
			controlMenu.add(getPauseMenuItem());
			controlMenu.add(getStopMenuItem());
		}
		return controlMenu;
	}
	
	private	JMenuItem getOpenMenuItem() {
		if (openMenuItem==null) {
			openMenuItem=new JMenuItem();
			openMenuItem.setText("Abrir");
			openMenuItem.setEnabled(true);
			openMenuItem.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					if (openedFile) {
						cerrar();
					}
					JFileChooser selecFile=new JFileChooser();
					selecFile.setFileSelectionMode(JFileChooser.FILES_ONLY);
					if (selecFile.showOpenDialog(Main.this)!=selecFile.CANCEL_OPTION) {
						filePath=selecFile.getSelectedFile().getPath();
						if (filePath.endsWith(".mp3")) {
							mlr = new MediaLocator("file:///"+filePath);
							try {
								player= Manager.createRealizedPlayer(mlr);
							} catch (NoPlayerException e1) {
								// TODO Auto-generated catch block
								e1.printStackTrace();
							} catch (CannotRealizeException e1) {
								// TODO Auto-generated catch block
								e1.printStackTrace();
							} catch (IOException e1) {
								// TODO Auto-generated catch block
								e1.printStackTrace();
							}
							openedFile=true;
							java.sql.Time t = new java.sql.Time(0);
							t.setTime((long) (player.getDuration().getSeconds()*1000));
							timeLeft.setText("-"+t.toString().substring(3));
							tRewind=new Timer(500,  new java.awt.event.ActionListener() {
								public void actionPerformed(java.awt.event.ActionEvent e) {
									secRewind=secRewind+1;
								}
							});
							openMenuItem.setEnabled(true);
							closeMenuItem.setEnabled(true);
							playMenuItem.setEnabled(true);
							pauseMenuItem.setEnabled(false);
							stopMenuItem.setEnabled(false);
							playButton.setEnabled(true);
							pauseButton.setEnabled(false);
							stopButton.setEnabled(false);
							rewindButton.setEnabled(false);
							forwardButton.setEnabled(false);
						}
						else {
							JOptionPane.showMessageDialog(null, "Formato no reconocido.\nSeleccione un archivo MP3.");
						}
					}
				}
			});
		}
		return openMenuItem;
	}
	
	private	JMenuItem getCloseMenuItem() {
		if (closeMenuItem==null) {
			closeMenuItem=new JMenuItem();
			closeMenuItem.setText("Cerrar");
			closeMenuItem.setEnabled(false);
			closeMenuItem.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					cerrar();
				}
			});
		}
		return closeMenuItem;
	}
	
	private void cerrar() {
		//Cerrar archivo
		
		openedFile=false;
		openMenuItem.setEnabled(true);
		closeMenuItem.setEnabled(false);
		playMenuItem.setEnabled(false);
		pauseMenuItem.setEnabled(false);
		stopMenuItem.setEnabled(false);
		playButton.setEnabled(false);
		pauseButton.setEnabled(false);
		stopButton.setEnabled(false);
		rewindButton.setEnabled(false);
		forwardButton.setEnabled(false);
	}
	
	private	JMenuItem getPlayMenuItem() {
		if (playMenuItem==null) {
			playMenuItem=new JMenuItem();
			playMenuItem.setText("Play");
			playMenuItem.setEnabled(false);
			playMenuItem.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					play();
				}
			});
		}
		return playMenuItem;
	}
	
	private	JMenuItem getPauseMenuItem() {
		if (pauseMenuItem==null) {
			pauseMenuItem=new JMenuItem();
			pauseMenuItem.setText("Pause");
			pauseMenuItem.setEnabled(false);
			pauseMenuItem.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					pause();
				}
			});
		}
		return pauseMenuItem;
	}
	
	private	JMenuItem getStopMenuItem() {
		if (stopMenuItem==null) {
			stopMenuItem=new JMenuItem();
			stopMenuItem.setText("Stop");
			stopMenuItem.setEnabled(false);
			stopMenuItem.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					stop();
				}
			});
		}
		return stopMenuItem;
	}
	
	private void play() {
		tActual=new Timer(1000, new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent e) {
				if (rewind) {
					double sec=player.getMediaTime().getSeconds()-secRewind;
					if (sec<0)
						sec=0;
					java.sql.Time t=new java.sql.Time((long) (sec*1000));
					timeCompleted.setText(t.toString().substring(3));
					t.setTime((long) (player.getDuration().getSeconds()*1000-sec*1000));
					timeLeft.setText("-"+t.toString().substring(3));
					double frac=sec/player.getDuration().getSeconds();
					double length=frac*MAX_LENGTH_PBAR;
					progressBar.setLength((int) length);
					progressBar.repaint();
				}
				else {
					java.sql.Time t = new java.sql.Time(0);
					t.setTime((long) (player.getMediaTime().getSeconds()*1000));
					timeCompleted.setText(t.toString().substring(3));
					t.setTime((long) (player.getDuration().getSeconds()*1000-player.getMediaTime().getSeconds()*1000));
					timeLeft.setText("-"+t.toString().substring(3));
					double frac=player.getMediaTime().getSeconds()/player.getDuration().getSeconds();
					double length=frac*MAX_LENGTH_PBAR;
					progressBar.setLength((int) length);
					progressBar.repaint();
				}
			}
		});
		if (rewind) {
			tRewind.stop();
			rewind=false;
			double sec=player.getMediaTime().getSeconds()-secRewind;
			if (sec<0)
				sec=0;
			javax.media.Time t=new javax.media.Time(sec);
			player.setMediaTime(t);
		}
		if (rate!=1){
			player.setRate(1);
			rate=1;
		}
		player.start();
		tActual.start();
		progressBar.setVisible(true);
		playMenuItem.setEnabled(false);
		pauseMenuItem.setEnabled(true);
		stopMenuItem.setEnabled(true);
		playButton.setEnabled(false);
		pauseButton.setEnabled(true);
		stopButton.setEnabled(true);
		rewindButton.setEnabled(true);
		forwardButton.setEnabled(true);
	}
	
	private void pause() {
		if (rewind) {
			tRewind.stop();
			rewind=false;
			double sec=player.getMediaTime().getSeconds()-secRewind;
			if (sec<0)
				sec=0;
			javax.media.Time t=new javax.media.Time(sec);
			player.setMediaTime(t);
			//player.start();
		}
		player.stop();
		tActual.stop();
		playMenuItem.setEnabled(true);
		pauseMenuItem.setEnabled(false);
		stopMenuItem.setEnabled(true);
		playButton.setEnabled(true);
		pauseButton.setEnabled(false);
		stopButton.setEnabled(true);
		rewindButton.setEnabled(false);
		forwardButton.setEnabled(false);
	}
	
	private void stop() {
		if (rewind) {
			tRewind.stop();
			rewind=false;
		}
		player.stop();
		tActual.stop();
		progressBar.setLength(0);
		progressBar.repaint();
		player.deallocate();
		player.prefetch();
		timeCompleted.setText("00:00");
		timeLeft.setText("-00:00");
		playMenuItem.setEnabled(true);
		pauseMenuItem.setEnabled(false);
		stopMenuItem.setEnabled(false);
		playButton.setEnabled(true);
		pauseButton.setEnabled(false);
		stopButton.setEnabled(false);
		rewindButton.setEnabled(false);
		forwardButton.setEnabled(false);
	}
	
	private void rewind() {
		rewind=true;
		secRewind=0;
		tRewind.restart();
		player.stop();
		playMenuItem.setEnabled(true);
		pauseMenuItem.setEnabled(true);
		stopMenuItem.setEnabled(true);
		playButton.setEnabled(true);
		pauseButton.setEnabled(true);
		stopButton.setEnabled(true);
		rewindButton.setEnabled(false);
		forwardButton.setEnabled(false);
	}
	
	private void forward() {
		player.setRate(player.getRate()*2);
		rate=rate*2;
		playMenuItem.setEnabled(true);
		pauseMenuItem.setEnabled(true);
		stopMenuItem.setEnabled(true);
		playButton.setEnabled(true);
		pauseButton.setEnabled(true);
		stopButton.setEnabled(true);
		rewindButton.setEnabled(false);
		forwardButton.setEnabled(false);
	}

}

